﻿using AntdUI;
using Modbus.Device;
using NetTaste;
using SqlSugar.Extensions;
using Sunny.UI.Win32;
using System.Diagnostics;
using System.Drawing;
using System.IO.Ports;
using System.Reflection;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
using System.Timers;
using Vanara;
using Vanara.PInvoke;
using WinFormium;
using WinFormium.Forms;

namespace TestPressure
{
#nullable enable
    internal class IndexFormium : Formium
    {
        #region 属性
        /// <summary>串口字典
        ///  串口地址为Key
        /// </summary>
        private Dictionary<string, SerialPort>? serialPortDic = new Dictionary<string, SerialPort> { };

        /// <summary>串口字典
        /// 设备编号为Key
        /// </summary>
        private Dictionary<string, SerialPort>? deviceSerialPortDic = new Dictionary<string, SerialPort> { };

        /// <summary>点位字典
        /// 
        /// </summary>
        private Dictionary<string, Dictionary<string, object>>? masterDic = new Dictionary<string, Dictionary<string, object>> { };

        /// <summary>界面点位字典
        /// 
        /// </summary>
        private Dictionary<string, string>? frormPointDic = new Dictionary<string, string> { };

        /// <summary>语音串口
        /// 
        /// </summary>
        private SerialPort? voiceSerialPort;

        /// <summary>语音设备地址
        /// 
        /// </summary>
        private string? voiceDeviceAddress;

        /// <summary>语音播报状态
        /// 
        /// </summary>
        private bool voiceBroadcastState = false;

        /// <summary>主计时器
        /// 
        /// </summary>
        private System.Timers.Timer MainCollectTimer;

        /// <summary>5502计时器
        /// 
        /// </summary>
        private System.Timers.Timer RemoteCollectTimer;

        /// <summary> 播报测试信息
        /// 
        /// </summary>
        private System.Timers.Timer BroadcastTestDataTimer;

        /// <summary> 播报错误
        /// 
        /// </summary>
        private System.Timers.Timer RemotePressureErrorTimer;

        /// <summary> 播报错误
        /// 
        /// </summary>
        private bool RemotePressureError;

        /// <summary> 远端温度错误
        /// 
        /// </summary>
        private bool RemoteTemplatureError;

        /// <summary>主温度
        /// 
        /// </summary>
        private double MainTemplature = 0;

        /// <summary>主压力
        /// 
        /// </summary>
        private double MainPressure = 0;

        /// <summary>远端温度
        /// 
        /// </summary>
        private double RemoteTemplature = 0;

        /// <summary>远端压力
        /// 
        /// </summary>
        private double RemotePressure = 0;

        /// <summary>工程
        /// 
        /// </summary>
        public ProjectItem? projectItem;

        /// <summary>模板
        /// 
        /// </summary>
        public Template template;

        /// <summary>阶段
        /// 
        /// </summary>
        List<string> StageList = new List<string>();
        string CurrentStage = string.Empty;

        /// <summary> 起步计时器
        /// 
        /// </summary>
        private System.Timers.Timer StartStageTimer;

        /// <summary> 起步阶段压力
        /// 
        /// </summary>
        double StartStagePressure;

        /// <summary> 起步阶段压力上限
        /// 
        /// </summary>
        double StartStagePressureMax = 0;

        /// <summary> 起步阶段压力下限
        /// 
        /// </summary>
        double StartStagePressureMin = 0;

        /// <summary>起步阶段时间
        /// 单位s
        /// </summary>
        int StartStageTime = 10;

        /// <summary>起步阶段保持
        /// 
        /// </summary>
        bool StartStageHolding = false;


        /// <summary> 保持阶段计时器
        /// 
        /// </summary>
        private System.Timers.Timer HoldingStageTimer;

        /// <summary> 保持阶段压力
        /// 
        /// </summary>
        double HoldingStagePressure;

        /// <summary> 保持阶段压力上限
        /// 
        /// </summary>
        double HoldingStagePressureMax = 0;

        /// <summary> 保持阶段压力下限
        /// 
        /// </summary>
        double HoldingStagePressureMin = 0;

        /// <summary> 保持阶段时间
        /// 单位s
        /// </summary>
        int HoldingStageTime = 120;

        /// <summary> 保持压力
        /// 
        /// </summary>
        bool HoldingPressure;

        #endregion 属性

        #region 自定义方法

        private System.Timers.Timer CollectTimer()
        {
            System.Timers.Timer timer = new System.Timers.Timer();
            timer.Interval = 1100;
            timer.AutoReset = true;//是否重复执行
            return timer;
        }

        /// <summary>设备列表
        /// 
        /// </summary>
        public void loadDeviceList()
        {
            List<Device> list = SqlSugarHelper.Inquireable<Device>(null);

            foreach (Device item in list)
            {
                Log.Debug("开始联接端口" + item.port_address);
                string deviceNumber = item.device_number.ToString();
                string portName = item.port_address; // 串口地址
                int baudRate = item.baudrate;   // 波特率
                var dataBits = 8;      // 数据位
                var stopBits = StopBits.One; // 停止位
                var parity = Parity.None;    // 校验位
                SerialPort serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
                if (!serialPortDic.ContainsKey(item.port_address))
                {
                    try
                    {
                        serialPort.Open();
                        if (serialPort.IsOpen)
                        {
                            Log.Info(portName + "：端口连接成功");
                            deviceSerialPortDic[item.device_number.ToString()] = serialPort;
                            serialPortDic[item.port_address] = serialPort;
                        }
                        else
                        {
                            Log.Info(portName + "：端口连接失败");
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(portName + "连接异常：" + ex.Message);
                    }
                }
                else
                {
                    deviceSerialPortDic[deviceNumber] = serialPortDic[item.port_address];
                    Log.Info(portName + "端口连接成功");
                }
            }

            Task.Run(() =>
            {
                loadDevicePointList();
            });
        }

        /// <summary>设备点位列表
        /// 
        /// </summary>
        public void loadDevicePointList()
        {
            List<DevicePoint> list = SqlSugarHelper.Inquireable<DevicePoint>(null);
            foreach (DevicePoint item in list)
            {
                if (deviceSerialPortDic.ContainsKey(item.device_number.ToString()))
                {
                    Dictionary<string, Object> obj = new Dictionary<string, Object> { };
                    obj["slaveAddress"] = item.device_address;
                    obj["startAddress"] = item.point_address;
                    obj["numberOfPoints"] = 1;
                    obj["rangeMin"] = item.range_min;
                    obj["rangeMax"] = item.range_max;
                    obj["signalMin"] = item.out_min;
                    obj["signalMax"] = item.out_max;
                    obj["pointName"] = item.point_name;
                    obj["devicePoint"] = item;
                    SerialPort serialPort = deviceSerialPortDic[item.device_number.ToString()];
                    ModbusSerialMaster master = ModbusSerialMaster.CreateRtu(serialPort);
                    master.Transport.WriteTimeout = 1000;
                    master.Transport.ReadTimeout = 1000;
                    obj["master"] = master;
                    obj["serialPort"] = serialPort;
                    obj["deviceAddress"] = item.device_address;
                    masterDic[item.point_number.ToString()] = obj;
                }
                else
                {
                    string log = string.Format("【{0}】连接异常,无法读取【{1}】", item.device_name, item.point_name);
                    Log.Error(log);
                }
            }

            Task.Run(() =>
            {
                loadFormPointList();
            });
        }

        /// <summary>界面点位列表
        /// 
        /// </summary>
        public void loadFormPointList()
        {
            List<FormPoint> list = SqlSugarHelper.Inquireable<FormPoint>(null);
            foreach (FormPoint item in list)
            {
                frormPointDic[item.form_point_name] = item.device_point_number.ToString();
            }

            Task.Run(() =>
            {
                SetupVoice();
            });

        }

        /// <summary>设置语音
        /// 
        /// </summary>
        private void SetupVoice()
        {
            string key = "voice";

            if (frormPointDic.ContainsKey(key))
            {
                string pointNumber = frormPointDic[key];
                if (masterDic.ContainsKey(pointNumber))
                {
                    Dictionary<string, object> dic = masterDic[pointNumber];
                    voiceSerialPort = (SerialPort)dic["serialPort"];
                    voiceDeviceAddress = dic["deviceAddress"].ToString();
                    int address = voiceDeviceAddress.ObjToInt();
                    voiceDeviceAddress = address.ToString("00");
                    voiceSerialPort.DataReceived += new SerialDataReceivedEventHandler(receivedData);//接收数据事件
                    voiceSerialPort.ReadTimeout = 3;
                    try
                    {
                        Byte[] strbyte = Tool.HexStringToBytes("CCDDAA");
                        voiceSerialPort.Write(strbyte, 0, strbyte.Length);//发送数据
                    }
                    catch (Exception ex)
                    {
                        Log.Error("语音模块联接指令下发异常：" + ex.Message);
                    }
                }
                else
                {
                    Log.Debug("语音master未创建");
                }
            }

            EvaluateJavaScriptAsync("endLoading()");
        }

        /// <summary>收到串口回复
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void receivedData(object sender, SerialDataReceivedEventArgs e)//接收数据
        {
            SerialPort serialPort = (SerialPort)sender;

            int len = serialPort.BytesToRead;//获取可以读取的字节数

            byte[] buff = new byte[len];//创建缓存数据数组

            try
            {
                serialPort.Read(buff, 0, len);//把数据读取到buff数组

                string back = BitConverter.ToString(buff, 0, buff.Length).Replace("-", "");
                if (back.Contains("CCDDAA"))
                {
                    Log.Info("语音模块已联接");
                    voiceBroadcastState = true;
                    if (voiceBroadcastState)
                    {
                        if (Config.BroadcastStart)
                        {
                            Broadcast("开机，请建立工程");
                        }
                        else
                        {
                            Log.Debug("未开启启动播报");
                        }
                    }
                    else
                    {
                        Log.Debug("语音功能异常");
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error("读取串口回复数据异常：" + ex.Message);
            }
        }

        /// <summary>播报
        /// 
        /// </summary>
        /// <param name="msg"></param>
        private void Broadcast(string content)
        {
            Log.Debug("语音播报：" + content);

            string lengthString = Tool.StringByteLength(content).ToString("X");
            if (lengthString.Length < 2)
            {
                lengthString = "0" + lengthString;
            }
            Log.Info(string.Format("数据长度:{0}", lengthString));
            string hexContent = Tool.GetHexFromChs(content);
            Log.Info(string.Format("数据内容:{0}", hexContent));

            string command = voiceDeviceAddress + "1000000000" + lengthString + hexContent;
            Log.Info(string.Format("指令:{0}", command));

            string crc = Tool.CRCForModbus(command);
            command = command + crc;
            if (voiceSerialPort != null)
            {
                if (voiceSerialPort.IsOpen)
                {
                    Byte[] strbyte = Tool.HexStringToBytes(command);
                    voiceSerialPort.Write(strbyte, 0, strbyte.Length);//发送数据
                    Log.Info(string.Format("下发播报指令：{0}", command));
                }
                else
                {
                    Log.Info("联接错误，无法下发播报指令");
                }
            }
        }

        /// <summary>播报试压数据
        /// 
        /// </summary>
        private void BroadcastTestData(object? sender, System.Timers.ElapsedEventArgs e)
        {
            if (Config.BroadcastTestData)
            {
                string msg = string.Format("主压力值{0}Mp，主温度{1}度，远端压力值{2}Mp，远端温度{3}度", MainPressure.ToString("0.##"), MainTemplature.ToString("0.##"), RemotePressure.ToString("0.##"), RemoteTemplature.ToString("0.##"));
                Broadcast(msg);
            }
        }

        private bool[] ReadCoilsAsync(string key, int count)
        {

            if (frormPointDic.ContainsKey(key))
            {
                string pointNumber = frormPointDic[key];


                if (masterDic.ContainsKey(pointNumber))
                {
                    Dictionary<string, object> dic = masterDic[pointNumber];

                    ModbusSerialMaster master = (ModbusSerialMaster)dic["master"];

                    // 从设备地址
                    byte slaveAddress = (byte)dic["slaveAddress"].ToString().ObjToInt();

                    // 读取起始寄存器地址
                    ushort startAddress = ushort.Parse(dic["startAddress"].ToString());

                    // 读取寄存器数量
                    ushort numberOfPoints = ushort.Parse(dic["numberOfPoints"].ToString());

                    if (count > 1)
                    {
                        numberOfPoints = ushort.Parse(count.ToString());
                    }
                    Task<bool[]> task = master.ReadCoilsAsync(slaveAddress, startAddress, numberOfPoints);
                    try
                    {
                        bool[] shorts = task.Result;
                        return shorts;
                    }
                    catch (Exception ex)
                    {
                        Log.Error(dic["pointName"] + " 状态异常：" + ex.Message);
                        return null;
                    }
                }
                else
                {
                    Log.Error(key + " master未创建");
                    return null;
                }
            }
            else
            {
                return null;
            }

        }

        private Dictionary<string, object> ReadInputRegistersAsync(string key)
        {
            if (frormPointDic.ContainsKey(key))
            {
                string pointNumber = frormPointDic[key];

                if (masterDic.ContainsKey(pointNumber))
                {
                    Dictionary<string, object> dic = masterDic[pointNumber];

                    ModbusSerialMaster master = (ModbusSerialMaster)dic["master"];

                    // 从设备地址
                    byte slaveAddress = (byte)dic["slaveAddress"].ToString().ObjToInt();

                    // 读取起始寄存器地址
                    ushort startAddress = ushort.Parse(dic["startAddress"].ToString());

                    // 读取寄存器数量
                    ushort numberOfPoints = ushort.Parse(dic["numberOfPoints"].ToString());
                    Task<ushort[]> task = master.ReadInputRegistersAsync(slaveAddress, startAddress, numberOfPoints);
                    try
                    {
                        ushort[] shorts = task.Result;
                        Dictionary<string, object> back = new Dictionary<string, object>();
                        back["data"] = shorts;
                        back["devicePoint"] = dic["devicePoint"];
                        return back;
                    }
                    catch (Exception ex)
                    {
                        Log.Error(dic["pointName"] + " 温度异常：" + ex.Message);
                        return null;
                    }
                }
                else
                {
                    Log.Error(key + " master未创建");
                    return null;
                }
            }
            else
            {
                Log.Debug(key + " 界面点位未创建");
                return null;
            }
        }

        private bool[] ReadInputsAsync(string key)
        {
            if (frormPointDic.ContainsKey(key))
            {
                string pointNumber = frormPointDic[key];

                if (masterDic.ContainsKey(pointNumber))
                {
                    Dictionary<string, object> dic = masterDic[pointNumber];

                    ModbusSerialMaster master = (ModbusSerialMaster)dic["master"];

                    // 从设备地址
                    byte slaveAddress = (byte)dic["slaveAddress"].ToString().ObjToInt();

                    // 读取起始寄存器地址
                    ushort startAddress = ushort.Parse(dic["startAddress"].ToString());

                    // 读取寄存器数量
                    ushort numberOfPoints = ushort.Parse(dic["numberOfPoints"].ToString());
                    Task<bool[]> task = master.ReadInputsAsync(slaveAddress, startAddress, numberOfPoints);
                    try
                    {
                        bool[] shorts = task.Result;
                        return shorts;
                    }
                    catch (Exception ex)
                    {
                        Log.Error(dic["pointName"] + " 状态获取异常：" + ex.Message);
                        return null;
                    }
                }
                else
                {
                    Log.Debug(key + " master未创建");
                    return null;
                }
            }
            else
            {

                Log.Debug(key + " 界面点位未创建");
                return null;
            }
        }
        private Dictionary<string, object> ReadHoldingRegistersAsync(string key)
        {
            if (frormPointDic.ContainsKey(key))
            {
                string pointNumber = frormPointDic[key];


                if (masterDic.ContainsKey(pointNumber))
                {
                    Dictionary<string, object> dic = masterDic[pointNumber];

                    ModbusSerialMaster master = (ModbusSerialMaster)dic["master"];

                    // 从设备地址
                    byte slaveAddress = (byte)dic["slaveAddress"].ToString().ObjToInt();

                    // 读取起始寄存器地址
                    ushort startAddress = ushort.Parse(dic["startAddress"].ToString());

                    // 读取寄存器数量
                    ushort numberOfPoints = ushort.Parse(dic["numberOfPoints"].ToString());

                    Task<ushort[]> task = master.ReadHoldingRegistersAsync(slaveAddress, startAddress, numberOfPoints);

                    try
                    {
                        ushort[] shorts = task.Result;
                        Dictionary<string, object> back = new Dictionary<string, object>();
                        back["data"] = shorts;
                        back["devicePoint"] = dic["devicePoint"];
                        return back;
                    }
                    catch (Exception ex)
                    {
                        Log.Error(dic["pointName"] + " 结果获取异常：" + ex.Message);
                        return null;
                    }
                }
                else
                {
                    Log.Debug(key + " master未创建");
                    return null;
                }
            }
            else
            {
                Log.Debug(key + " 界面点位未创建");
                return null;
            }
        }

        /// <summary>远端压力错误
        /// 
        /// </summary>
        private void BroadcastRemotPressureError(object? sender, System.Timers.ElapsedEventArgs e)
        {
            if (Config.BroadcastRemoteError)
            {
                if (RemotePressureError == true)
                {
                    Broadcast("远端压力值采集失败");
                }
                if (RemoteTemplatureError == true)
                {
                    Broadcast("远端温度值采集失败");
                }

                if (!RemotePressureError && !RemoteTemplatureError)
                {
                    this.RemotePressureErrorTimer.Stop();
                }
            }
            else
            {
                Log.Debug("未开启播报远端异常");
            }
        }

        /// <summary> 起步阶段
        /// 
        /// </summary>
        private void CheckStartStage(object? sender, System.Timers.ElapsedEventArgs e)
        {
            if ((MainPressure > StartStagePressureMin ) && (!StartStageHolding))
            {
                string msg = string.Format("当前压力{0}，满足{1}的标准", MainPressure, StartStagePressureMin);
                Log.Debug(msg);
                StartStageHolding = true;
            }

            if (StartStageHolding)
            {
                Log.Debug("起步阶段剩余："+StartStageTime.ToString());
                if (StartStageTime == 0)
                {
                    Log.Debug("起步阶段验证通过");
                    if (StageList.Count > 0)
                    {
                        StartStageTimer.Stop();
                        ResertStartTimer();
                        UpdateStageInfo(StageList[0]);
                        HoldingStageTime = 20;
                        HoldingStageTimer.Start(); 
                    }
                }
                else
                {
                    if ((MainPressure >= StartStagePressureMin))
                    {
                        StartStageTime--;
                    }
                    else
                    {
                        ResertStartTimer();
                    }
                }
            }
        }

        /// <summary>重置起步计时器
        /// 
        /// </summary>
        private void ResertStartTimer()
        {
            StartStageHolding = false;
            StartStageTime = 120;
        }

        /// <summary> 保持阶段
        /// 
        /// </summary>
        private void CheckHoldingStage(object? sender, System.Timers.ElapsedEventArgs e)
        {
            string stageString = StageString(StageList[0]);
            if (HoldingStageTime == 0)
            {
                if (HoldingStageTimer is not  null)
                {
                    HoldingStageTimer.Stop();
                }
                string msg = string.Format("{0}检测合格，请注意安全", stageString);
                Broadcast(msg);
                msg = string.Format("updateStage('#{0}Stage','合格')", StageList[0]);
                Log.Debug(msg);
                EvaluateJavaScriptAsync(msg);
            }
            else
            {
                Log.Debug(stageString + "剩余：" + HoldingStageTime.ToString());
                if (MainPressure >= HoldingStagePressureMin && MainPressure <= HoldingStagePressureMax)
                {
                    HoldingStageTime--;
                    string msg = string.Format("updateStage('#{0}Stage','{1}')", StageList[0], HoldingStageTime);
                    Log.Debug(msg);
                    EvaluateJavaScriptAsync(msg);
                }
                else
                {
                    string msg = string.Format("{0}--{1}--{2}", MainPressure, HoldingStagePressureMin, HoldingStagePressureMax);
                    Log.Debug(msg);
                }
            }
        }

        /// <summary> 更新阶段信息
        /// 
        /// </summary>
        /// <param name="stage"></param>
        private void UpdateStageInfo(string stage)
        {
            double pressure = 0;
            int time = 0;
            int stage_estimate = 0;
            float stage_estimate_value = 0;
            string stageString = StageString(stage);
            if (stage == "first")
            {
                Log.Debug("第一阶段");
                pressure = template.first_stage_pressure;
                time = (int)(template.first_stage_minute * 60 * 60);
                stage_estimate = template.first_stage_estimate;
                stage_estimate_value = template.first_stage_estimate_value;
            }
            else if (stage == "second")
            {
                pressure = template.second_stage_pressure;
                time = (int)(template.second_stage_minute * 60 * 60);
                stage_estimate = template.second_stage_estimate;
                stage_estimate_value = template.second_stage_estimate_value;
            }
            else if (stage == "third")
            {
                pressure = template.third_stage_pressure;
                time = (int)(template.third_stage_minute * 60 * 60);
                stage_estimate = template.third_stage_estimate;
                stage_estimate_value = template.third_stage_estimate_value;
            }
            else if (stage == "intensity")
            {
                pressure = template.intensity_stage_pressure;
                time = (int)(template.intensity_stage_minute * 60 * 60);
                stage_estimate = template.intensity_stage_estimate;
                stage_estimate_value = template.intensity_stage_estimate_value;
            }
            else if (stage == "rigor")
            {
                pressure = template.rigor_stage_pressure;
                time = (int)(template.rigor_stage_minute * 60 * 60);
                stage_estimate = template.rigor_stage_estimate;
                stage_estimate_value = template.rigor_stage_estimate_value;
            }

            HoldingStagePressure = pressure;

            if (stage_estimate == 1) //范围
            {
                HoldingStagePressureMax = Math.Round(pressure * (1 - (stage_estimate_value / 100)),3);
                HoldingStagePressureMin = Math.Round(pressure * (1 + (stage_estimate_value / 100)), 3);
            }
            else
            {
                HoldingStagePressureMin = Math.Round(pressure - stage_estimate_value, 3);
                HoldingStagePressureMax = Math.Round(pressure + stage_estimate_value, 3);
            }
            HoldingStageTime = time;
            string msg = string.Format("{0}{1}分钟开始倒计时，请注意安全", stageString, HoldingStageTime / 60);
            Broadcast(msg);
            Log.Debug(HoldingStagePressure + "--" + HoldingStagePressureMin + "--" + HoldingStagePressureMax + "--" + HoldingStageTime); 
        }

        private string StageString(string stage)
        {
            string stageString = "";
            if (stage == "first")
            {
                stageString = "第一阶段";
            }
            else if (stage == "second")
            {
                stageString = "第二阶段";
            }
            else if (stage == "third")
            {
                stageString = "第三阶段";
            }
            else if (stage == "intensity")
            {
                stageString = "强度实验阶段";
            }
            else if (stage == "rigor")
            {
                stageString = "严密性实验阶段";
            }
            return stageString;
        }

        /// <summary>配置
        /// 
        /// </summary>
        public void Setup()
        {
            this.MainCollectTimer = CollectTimer();
            this.MainCollectTimer.Elapsed += ReadMainRegister;

            this.RemoteCollectTimer = CollectTimer();
            this.RemoteCollectTimer.Elapsed += ReadRemoteRegister;

            int timeInterval = Config.BroadcastTestDataTimeInterval;
            this.BroadcastTestDataTimer = new System.Timers.Timer();
            this.BroadcastTestDataTimer.Interval = 1000 * timeInterval;
            this.BroadcastTestDataTimer.AutoReset = true;//是否重复执行
            this.BroadcastTestDataTimer.Elapsed += BroadcastTestData;

            timeInterval = Config.BroadcastRemoteErrorTimeInterval;
            this.RemotePressureErrorTimer = new System.Timers.Timer();
            this.RemotePressureErrorTimer.Interval = 1000 * timeInterval;
            this.RemotePressureErrorTimer.AutoReset = true;//是否重复执行
            this.RemotePressureErrorTimer.Elapsed += BroadcastRemotPressureError;

            this.StartStageTimer = new System.Timers.Timer();
            this.StartStageTimer.Interval = 1000;
            this.StartStageTimer.AutoReset = true;//是否重复执行
            this.StartStageTimer.Elapsed += CheckStartStage;

            this.HoldingStageTimer = new System.Timers.Timer();
            this.HoldingStageTimer.Interval = 1000;
            this.HoldingStageTimer.AutoReset = true;//是否重复执行
            this.HoldingStageTimer.Elapsed += CheckHoldingStage;
            
        }

        /// <summary>读取主设备
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ReadMainRegister(object? sender, System.Timers.ElapsedEventArgs e)
        {
            /*
            int sleep = 100;
            bool[] res = ReadCoilsAsync("MFan", 1);
            if (res != null)
            {
                Log.Debug("主风扇状态：" + res[0]);
            }
            else
            {
                Log.Error("主机箱风扇获取失败");
            }

            Thread.Sleep(sleep);*/
            Dictionary<string, object> back = ReadHoldingRegistersAsync("RPressure");
            if (back != null)
            {
                ushort[] shorts = (ushort[])back["data"];

                DevicePoint point = (DevicePoint)back["devicePoint"];

                float outMax = point.out_max;

                float outMin = point.out_min;

                float rangeMax = point.range_max;

                float rangeMin = point.range_min;

                double pressure = (shorts[0] - outMin) / (outMax - outMin);
                pressure = Math.Round(pressure * (rangeMax - rangeMin) + rangeMin, 3);
                string item = "#mainPressure";
                string alarm = "0";
                if (pressure > point.alarm_hight)
                {
                    alarm = "1";
                    string msg = string.Format("【{0}:】【{1}】超过限高阈值【{2}】", point.point_name, pressure, point.alarm_hight);
                    Log.Debug(msg);
                }
                else if (pressure < point.alarm_low)
                {
                    alarm = "1";
                    string msg = string.Format("【{0}:】【{1}】低于最低阈值【{2}】", point.point_name, pressure, point.alarm_low);
                    Log.Debug(msg);
                }
                else
                {
                    string msg = string.Format("【{0}:】【{1}】", point.point_name, pressure);
                    Log.Debug(msg);
                }
                MainPressure = pressure;
                string data = string.Format("setup('{0}','{1}','{2}')", item, pressure, alarm);
                EvaluateJavaScriptAsync(data);
                if (StartStagePressure > 0)
                {
                    StartStagePressureMax = Math.Round(StartStagePressure * (1 + (point.error_range / 100)),3);
                    StartStagePressureMin = Math.Round(StartStagePressure * (1 - (point.error_range / 100)),3);
                }
                else
                {
                    Log.Error("❌请注意起步压力异常❌");
                }
            }
            else
            {
                Log.Error("主压力获取失败");
            }
            /*
            Thread.Sleep(sleep);
            back = ReadInputRegistersAsync("MTemplature");
            if (back != null)
            {

                ushort[] shorts = (ushort[])back["data"];
                DevicePoint point = (DevicePoint)back["devicePoint"];
                float temperature = (Tool.ConvertUshort(shorts[0]) / 10.0f);
                string item = "#mainTemplature";
                string alarm = "0";
                if (temperature > point.alarm_hight)
                {
                    alarm = "1";
                    string msg = string.Format("【{0}:】【{1}】超过限高阈值【{2}】", point.point_name, temperature, point.alarm_hight);
                    Log.Debug(msg);
                }
                else
                {
                    string msg = string.Format("【{0}:】【{1}】", point.point_name, temperature);
                    Log.Debug(msg);
                }
                MainTemplature = temperature;
                string data = string.Format("setup('{0}','{1}','{2}')", item, temperature, alarm);
                EvaluateJavaScriptAsync(data);
            }
            else
            {
                Log.Error("主温度获取失败");
            }
            Thread.Sleep(sleep);*/
        }

        /// <summary>读取远端设备
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ReadRemoteRegister(object? sender, System.Timers.ElapsedEventArgs e)
        {
            /*
            int sleep = 100;
            bool[]  res = ReadCoilsAsync("RFan", 2);
            if (res != null)
            {
                Log.Debug(string.Format("远端风扇：【{0}】 采集标志：【{1}】", res[0], res[1]));
            }
            else
            {
                Log.Error("远端机箱风扇获取失败");
            }

            Thread.Sleep(sleep);
            Dictionary<string, object> back = ReadHoldingRegistersAsync("RPressure");
            if (back != null)
            {
                ushort[] shorts = (ushort[])back["data"];

                DevicePoint point = (DevicePoint)back["devicePoint"];

                float outMax = point.out_max;

                float outMin = point.out_min;

                float rangeMax = point.range_max;

                float rangeMin = point.range_min;

                double pressure = (shorts[0] - outMin) / (outMax - outMin);
                pressure = Math.Round(pressure * (rangeMax - rangeMin) + rangeMin, 3);
                string item = "#remotePressure";
                string alarm = "0";
                if (pressure > point.alarm_hight)
                {
                    alarm = "1";
                    string msg = string.Format("【{0}:】【{1}】超过限高阈值【{2}】", point.point_name, pressure, point.alarm_hight);
                    Log.Debug(msg);
                }
                else if (pressure < point.alarm_low)
                {
                    alarm = "1";
                    string msg = string.Format("【{0}:】【{1}】低于最低阈值【{2}】", point.point_name, pressure, point.alarm_low);
                    Log.Debug(msg);
                }
                else
                {
                    string msg = string.Format("【{0}:】【{1}】", point.point_name, pressure);
                    Log.Debug(msg);
                }
                RemotePressure = pressure;
                string data = string.Format("setup('{0}','{1}','{2}')", item, pressure, alarm);
                EvaluateJavaScriptAsync(data);
                RemotePressureError = false;
            }
            else
            {
                if (!this.RemotePressureErrorTimer.Enabled)
                {
                    this.RemotePressureErrorTimer.Start();
                }
                RemotePressureError = true;
                Log.Error("远端压力获取失败");
            }

            Thread.Sleep(sleep);
            back = ReadInputRegistersAsync("RTemplature");
            if (back != null)
            {

                ushort[] shorts = (ushort[])back["data"];
                DevicePoint point = (DevicePoint)back["devicePoint"];
                float temperature = (Tool.ConvertUshort(shorts[0]) / 10.0f);
                string item = "#remoteTemplature";
                string alarm = "0";
                if (temperature > point.alarm_hight)
                {
                    alarm = "1";
                    string msg = string.Format("【{0}:】【{1}】超过限高阈值【{2}】", point.point_name, temperature, point.alarm_hight);
                    Log.Debug(msg);
                }
                else
                {
                    string msg = string.Format("【{0}:】【{1}】", point.point_name, temperature);
                    Log.Debug(msg);
                }
                RemoteTemplature = temperature;
                string data = string.Format("setup('{0}','{1}','{2}')", item, temperature, alarm);
                EvaluateJavaScriptAsync(data);
                RemoteTemplatureError = false;
            }
            else
            {
                if (!this.RemotePressureErrorTimer.Enabled)
                {
                    this.RemotePressureErrorTimer.Start();
                }
                RemoteTemplatureError = true;
                Log.Error("远端温度获取失败");
            }
            Thread.Sleep(sleep);*/
        }

        /// <summary>注册方法
        /// 
        /// </summary>
        private void RegisterJavaScriptMessagHandler()
        {
            RegisterJavaScriptMessagHandler("ShowForm", args =>
            {
                string data = args; // args: JavaScriptValue 类型，此处显式转换为 string 类型
                if (data == "Collect")
                {
                    if (projectItem is not null)
                    {
                        MainCollectTimer.Start();
                        RemoteCollectTimer.Start();
                        BroadcastTestDataTimer.Start();
                        EvaluateJavaScriptAsync("startcollect()");
                        StartStageTimer.Start();
                    }
                    else
                    {
                        InvokeOnUIThread(() =>
                        {
                            MessageBox.Show("当前无工程，无法开始采集！", "友情提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        });
                    }
                }
                else
                {
                    InvokeOnUIThread(() =>
                    {
                        if (data is not null)
                        {
                            if (data.Length > 0)
                            {
                                if (data == "ProjectManageForm")
                                {
                                    ProjectManageForm frm = new ProjectManageForm();
                                    frm.form = this;
                                    frm.ShowDialog();
                                }
                                else
                                {
                                    data = "TestPressure." + data;
                                    object obj = Assembly.GetExecutingAssembly().CreateInstance(data);
                                    if (obj != null)
                                    {
                                        Form frm = obj as Form;
                                        frm.ShowDialog(this);
                                    }
                                }
                            }
                        }
                    });
                }
            });

            ///停止采集
            RegisterJavaScriptMessagHandler("StopCollect", args =>
            {
                MainCollectTimer.Stop();
                RemoteCollectTimer.Stop();
                BroadcastTestDataTimer.Stop();
                RemotePressureErrorTimer.Stop();
                StartStageTimer.Stop();
                if (HoldingStageTimer is not null)
                {
                    HoldingStageTimer.Stop();
                }
            });
        }

        /// <summary>刷新工程信息
        /// 
        /// </summary>
        public void ReloadProjectInfo()
        {
            if (projectItem is not null)
            {
                Dictionary<string, System.Object> where = new Dictionary<string, System.Object>();
                where["template_number"] = projectItem.template_id;
                List<Template> list = SqlSugarHelper.Inquireable<Template>(where);
                if (list.Count == 0)
                {
                    string data = string.Format("【{0}】编号的模板不存在", where["template_number"]);
                    MessageBox.Show(data);
                    projectItem = null;
                }
                else
                {
                    template = list[0];
                    string data = string.Format("projectInfo('{0}','{1}')", projectItem.project_number, projectItem.project_name);
                    EvaluateJavaScriptAsync(data);

                    if (template.first_stage_pressure > 0)
                    {
                        StageList.Add("first");
                        if (StartStagePressure == 0)
                        {
                            StartStagePressure = Math.Round(template.first_stage_pressure,3);
                        }
                    }
                    else
                    {
                        string msg = string.Format("updateStage('#firstStage','--')");
                        EvaluateJavaScriptAsync(msg);
                    }

                    if (template.second_stage_pressure > 0)
                    {
                        StageList.Add("second");
                        if (StartStagePressure == 0)
                        {
                            StartStagePressure = Math.Round(template.second_stage_pressure, 3);
                        }
                    }
                    else
                    {
                        string msg = string.Format("updateStage('#secondStage','--')");
                        EvaluateJavaScriptAsync(msg);
                    }

                    if (template.third_stage_pressure > 0)
                    {
                        StageList.Add("third");
                        if (StartStagePressure == 0)
                        {
                            StartStagePressure = Math.Round(template.third_stage_pressure, 3);
                        }
                    }
                    else
                    {
                        string msg = string.Format("updateStage('#thirdStage','--')");
                        EvaluateJavaScriptAsync(msg);
                    }

                    if (template.intensity_stage_pressure > 0)
                    {
                        StageList.Add("intensity");
                        if (StartStagePressure == 0)
                        {
                            StartStagePressure = Math.Round(template.intensity_stage_pressure, 3);
                        }
                    }
                    else
                    {
                        string msg = string.Format("updateStage('#intensityStage','--')");
                        EvaluateJavaScriptAsync(msg);
                    }

                    if (template.rigor_stage_pressure > 0)
                    {
                        StageList.Add("rigor");
                        if (StartStagePressure == 0)
                        {
                            StartStagePressure = Math.Round(template.rigor_stage_pressure, 3);
                        }
                    }
                    else
                    {
                        string msg = string.Format("updateStage('#rigorStage','--')");
                        EvaluateJavaScriptAsync(msg);
                    }

                    CurrentStage = "start";
                }
            }
            else
            {
                InvokeOnUIThread(() =>
                {
                    MessageBox.Show("请重新选择工程");
                });
            }
        }

        #endregion

        #region 系统方法
        public IndexFormium()
        {
            ///不显示窗体过度动画
            EnableSplashScreen = false;
            Icon icon = new Icon("logo.ico");
            Icon = icon;
            Sizable = false;//禁止调整窗口大小
            Url = "http://testpressure.app.local/Index.html";
            Move += Formiun_Move;
            Loaded += IndexFormium_Loaded;
            PageLoadEnd += IndexFormium_PageLoadEnd;
            RegisterJavaScriptMessagHandler();
        }

        /// <summary>页面加载完成
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void IndexFormium_PageLoadEnd(object? sender, PageLoadEndEventArgs e)
        {
            Task.Run(() =>
            {
                EvaluateJavaScriptAsync("loading()");
                loadDeviceList();
            });
        }

        /// <summary>窗体加载完成
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void IndexFormium_Loaded(object? sender, BrowserEventArgs e)
        {   
            Setup();
        }

        protected override FormStyle ConfigureWindowStyle(WindowStyleBuilder builder)
        {
            var style = builder.UseSystemForm();
            style.TitleBar = true;
            style.DefaultAppTitle = "试压数据采集";
            style.Maximizable = false;
            style.WindowState = FormiumWindowState.Maximized;
            style.StartCentered = StartCenteredMode.CenterScreen;
            style.ColorMode = FormiumColorMode.Light;
            Screen[] allScreens = Screen.AllScreens;
            if (Screen.PrimaryScreen is not null)
            {
                style.MinimumSize = Screen.PrimaryScreen.WorkingArea.Size;
                style.MaximumSize = new Size(Screen.PrimaryScreen.WorkingArea.Size.Width - 200, Screen.PrimaryScreen.WorkingArea.Size.Height -200);
            }
            return style;
        }

        private void Formiun_Move(object? sender, System.EventArgs s) {
            Location = new Point(0, 0);
        }
        #endregion
    }
}
